package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huiminpay.common.cache.Cache;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.StringUtil;
import com.huiminpay.transaction.api.IPayChannelParamService;
import com.huiminpay.transaction.convert.PayChannelParamConvert;
import com.huiminpay.transaction.dto.PayChannelParamDTO;
import com.huiminpay.transaction.entity.AppPlatformChannel;
import com.huiminpay.transaction.entity.PayChannelParam;
import com.huiminpay.transaction.mapper.AppPlatformChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelParamMapper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;


@Service
public class IPayChannelParamServiceImpl implements IPayChannelParamService {



    @Autowired
    PayChannelParamMapper payChannelParamMapper;

    @Autowired
    AppPlatformChannelMapper appPlatformChannelMapper;

    @Autowired
    Cache cache;

    String keyPre = "SH_PAY_PARAM";


    @Override
    public void savePayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BusinessException{
        //非空校验
        if (StringUtil.isEmpty(payChannelParamDTO.getAppId())){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (StringUtil.isEmpty(payChannelParamDTO.getPlatformChannelCode())){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (StringUtil.isEmpty(payChannelParamDTO.getPayChannel())){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (StringUtil.isEmpty(payChannelParamDTO.getParam())){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (StringUtil.isEmpty(payChannelParamDTO.getChannelName())){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (null == payChannelParamDTO.getMerchantId()){
            throw new BusinessException(CommonErrorCode.E_200202);
        }


        //1.通过AppID和platformCode得到唯一的appPlatformChannelId
        Long appPlatformChannelId =
                getAppPlatformChannelId(payChannelParamDTO.getAppId(),payChannelParamDTO.getPlatformChannelCode());

        //2.根据APP_PLATFORM_CHANNEL_ID和payChannel查询到唯一的PayParam
        PayChannelParam payChannelParam =
                getPayChannelParamByAppPlatIdAndPay(payChannelParamDTO.getPayChannel(), appPlatformChannelId);

        //对象转换
        payChannelParamDTO.setAppPlatformChannelId(appPlatformChannelId);
        PayChannelParam payChannelParam1 = PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamDTO);
        //3.如果有数据就更新，如果没有就新增
        if (payChannelParam == null){
            payChannelParamMapper.insert(payChannelParam1);
        }else {
            //更新支付渠道参数
            payChannelParam1.setId(payChannelParam.getId());
            payChannelParamMapper.updateById(payChannelParam1);

        }
        //操作完成以后更新缓存
        List<PayChannelParamDTO> payChannelParamDTOS =
                queryPayChannelParams(payChannelParamDTO.getAppId(), payChannelParamDTO.getPlatformChannelCode());

        //处理redis，操作PayParam时更新redis缓存
        updataCache(payChannelParamDTO.getAppId()
                ,payChannelParamDTO.getPlatformChannelCode()
                ,payChannelParamDTOS);

    }



    @Override
    public PayChannelParamDTO queryPayChannelParam(String appId, String platformChannel, String payChannel) {

        //非空判断
        if (StringUtil.isEmpty(appId)){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (StringUtil.isEmpty(platformChannel)){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (StringUtil.isEmpty(payChannel)){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        //1.构建redisKey
        String key = keyPre + appId + platformChannel;

        //2.查询key存不存在
        if (cache.exists(key)){
            //有，直接返回值
            String value = cache.get(key);
            //将json转换为list对象
            List<PayChannelParamDTO> payChannelParamDTOS = JSON.parseArray(value, PayChannelParamDTO.class);
            //查询到具体的支付通道参数
            for (PayChannelParamDTO p : payChannelParamDTOS){
                if (payChannel.equals(p.getPayChannel())){
                    return p;
                }
            }
            //此通道参数不存在
            return null;
        }else {
            //不存在，进行查询然后写入cache

            //1.通过AppID和platformCode得到唯一的appPlatformChannelId
            Long appPlatformChannelId = getAppPlatformChannelId(appId, platformChannel);

            //通过appPlatformChannelId 得到 PayChannelParam列表
            QueryWrapper<PayChannelParam> qw = new QueryWrapper<>();
            qw.lambda().eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId);
            List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(qw);
            List<PayChannelParamDTO> payChannelParamDTOS =
                    PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
            //存储到缓存，然后返回值
            cache.set(key,JSON.toJSONString(payChannelParamDTOS));
           for (PayChannelParamDTO p : payChannelParamDTOS){
               if (payChannel.equals(p.getPayChannel())){
                   return p;
               }
           }
           return null;
        }
    }


    @Override
    public List<PayChannelParamDTO> queryPayChannelParams(String appId, String platformChannel) {

        //非空判断
        if (StringUtil.isEmpty(appId)){
            throw new BusinessException(CommonErrorCode.E_200202);
        }
        if (StringUtil.isEmpty(platformChannel)){
            throw new BusinessException(CommonErrorCode.E_200202);
        }

        //1.构建redisKey
        String key = keyPre + appId + platformChannel;
        //2.查询key存不存在
        if (cache.exists(key)){
            //有，直接返回值
            String value = cache.get(key);
            //将json转换为list对象
            return JSON.parseArray(value,PayChannelParamDTO.class);
        }else {
            //不存在，进行查询然后写入cache

            //1.通过AppID和platformCode得到唯一的appPlatformChannelId
            Long appPlatformChannelId = getAppPlatformChannelId(appId, platformChannel);

            //通过appPlatformChannelId 得到 PayChannelParam列表
            QueryWrapper<PayChannelParam> qw = new QueryWrapper<>();
            qw.lambda().eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId);
            List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(qw);
            List<PayChannelParamDTO> payChannelParamDTOS =
                    PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
            //存储到缓存，然后返回值
            cache.set(key,JSON.toJSONString(payChannelParamDTOS));
            return payChannelParamDTOS;
        }
    }


    //////////////////////////////////公共方法区/////////////////////////////////////////

    //1.通过AppID和platformCode得到唯一的appPlatformChannelId
    private Long getAppPlatformChannelId(String appId, String platformChannel) {
        //1.通过AppID和platformCode得到唯一的APP_PLATFORM_CHANNEL_ID
        QueryWrapper<AppPlatformChannel> qw = new QueryWrapper<>();
        qw.lambda().eq(AppPlatformChannel::getAppId,appId)
                .eq(AppPlatformChannel::getPlatformChannel,platformChannel);
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(qw);
        //查询的结果如果为空则表示应用没有绑定该服务
        if (appPlatformChannel == null){
            throw new BusinessException(CommonErrorCode.E_200210);
        }
        Long appPlatformChannelId = appPlatformChannel.getId();
        return appPlatformChannelId;
    }

    //2.根据appPlatformChannelId 和 PayChannel查询到唯一的PayChannelParam
    private PayChannelParam getPayChannelParamByAppPlatIdAndPay(
            String PayChannel, Long appPlatformChannelId) {

        QueryWrapper<PayChannelParam> qw = new QueryWrapper<>();
        qw.lambda().eq(PayChannelParam::getAppPlatformChannelId,appPlatformChannelId)
                .eq(PayChannelParam::getPayChannel,PayChannel);

        return payChannelParamMapper.selectOne(qw);
    }

    //3.redis更新操作
    private void updataCache(String appId, String platformCode,List data) throws BusinessException {
        //1.构建redisKey
        String key = keyPre + appId + platformCode;

        //2.查询key存不存在
        if (cache.exists(key)){
            //有，删除原有的值
            cache.del(key);
        }
        //3.存入新的缓存
        if (data == null){
            throw new BusinessException(CommonErrorCode.E_300007);
        }
        cache.set(key, JSON.toJSONString(data));
    }

    //4.redis查询操作
    private List<PayChannelParamDTO> queryCache(String appId, String platformCode) throws BusinessException {
        //1.构建redisKey
        String key = keyPre + appId + platformCode;

        //2.查询key存不存在
        if (cache.exists(key)){
            //有，直接返回值
            String value = cache.get(key);
            //将json转换为list对象
            return JSON.parseArray(value,PayChannelParamDTO.class);
        }else {
            //不存在，进行查询然后写入cache
            List<PayChannelParamDTO> payChannelParamDTOS = queryPayChannelParams(appId, platformCode);
            if (payChannelParamDTOS == null){
                throw new BusinessException(CommonErrorCode.E_300008);
            }
            //存储到缓存，然后返回值
            cache.set(key,JSON.toJSONString(payChannelParamDTOS));
            return payChannelParamDTOS;
        }

    }

}
